import random
import time
from typing import Optional

from .config import Config
from .relay import Relay
from .supply import Supply
from loguru import logger


class Control:
    def __init__(self, config: Config):
        self.config = config
        self.relay_port = self.config['Relay', 'port']
        self.relay_rate = self.config['Relay', 'rate']
        self.supply_port = self.config['Supply', 'port']
        self.supply_rate = self.config['Supply', 'rate']
        self.supply_channel = int(self.config['Channel', 'supply'])
        self.sleep_channel = int(self.config['Channel', 'sleep'])
        self.relay = Relay(self.relay_port, int(self.relay_rate))
        self.supply = Supply(self.supply_port, int(self.supply_rate))
        self.fun = {
            'acc_off': self.acc_off,
            'acc_on': self.acc_on,
            'acc_off_10s': self.acc_off_10s,
            'acc_off_black_screen': self.acc_off_black_screen,
            'acc_off_wake_sleep': self.acc_off_wake_sleep,
            'acc_on_wake_on': self.acc_on_wake_on,
            'acc_on_normal': self.acc_on_normal,
            'acc_break': self.acc_break,
            'supply_off_10ms': self.supply_off_10ms,
            'supply_off_40ms': self.supply_off_40ms,
            'supply_off_100ms': self.supply_off_100ms,
            'supply_off_1s': self.supply_off_1s,
            'supply_off_3s': self.supply_off_3s,
            'supply_off_5s': self.supply_off_5s,
            'set_voltage_24v': self.set_voltage_24v,
            'set_voltage_21_7v': self.set_voltage_21_7v,
            'set_voltage_22_5v': self.set_voltage_22_5v,
            'set_voltage_15_5v': self.set_voltage_15_5v,
            'set_voltage_5_3v': self.set_voltage_5_3v,
            'wait_3s': self.wait_3s,
            'boot_half': self.boot_half,
            'boot_norm': self.boot_norm

        }

    def acc_off_10s(self, wait_time: Optional[float] = None):
        """acc off 10秒内未进入黑屏状态"""
        if wait_time is None:
            wait_time = random.uniform(0, 10)
        else:
            wait_time = 0 if wait_time < 0 else wait_time
            wait_time = 10 if wait_time > 10 else wait_time
        logger.info('ACC OFF')
        self.relay.close_relay(self.sleep_channel)
        logger.info(f'等待{wait_time}s')
        time.sleep(wait_time)

    def acc_off(self):
        self.relay.close_relay(self.sleep_channel)

    def acc_on(self):
        self.relay.open_relay(self.sleep_channel)

    def acc_off_black_screen(self, wait_time: Optional[float] = None):
        """acc off 30秒内进入黑屏状态"""
        if wait_time is None:
            wait_time = random.uniform(10, 30)
        else:
            wait_time = 10 if wait_time < 10 else wait_time
            wait_time = 30 if wait_time > 30 else wait_time
        logger.info('ACC OFF')
        self.relay.close_relay(self.sleep_channel)
        logger.info(f'等待{wait_time}s')
        time.sleep(wait_time)

    def acc_off_wake_sleep(self, wait_time: Optional[float] = None):
        """acc off 40秒内进入休眠状态"""
        if wait_time is None:
            wait_time = random.uniform(40, 60)
        else:
            wait_time = 40 if wait_time < 40 else wait_time
        logger.info('ACC OFF')
        self.relay.close_relay(self.sleep_channel)
        logger.info(f'等待{wait_time}s')
        time.sleep(wait_time)

    def acc_on_wake_on(self, wait_time: Optional[float] = None):
        """acc on 20秒内进入唤醒状态"""
        if wait_time is None:
            wait_time = random.uniform(1, 20)
        else:
            wait_time = 0 if wait_time < 0 else wait_time
            wait_time = 20 if wait_time > 20 else wait_time
        logger.info('ACC ON')
        self.relay.open_relay(self.sleep_channel)
        logger.info(f'等待{wait_time}s')
        time.sleep(wait_time)

    def acc_on_normal(self, wait_time: Optional[float] = None):
        """acc on 20秒后进入正常状态"""
        if wait_time is None:
            wait_time = random.uniform(20, 30)
        else:
            wait_time = 20 if wait_time < 20 else wait_time
        logger.info('ACC ON')
        self.relay.open_relay(self.sleep_channel)
        logger.info(f'等待{wait_time}s')
        time.sleep(wait_time)

    def acc_break(self):
        """打断ACC ON、ACC OFF"""
        status = self.relay.read(self.sleep_channel)
        logger.info(f'ACC当前状态为{'打开' if status else '关闭'}')
        logger.info(f'{'关闭' if status else '打开'}ACC')
        if status:
            self.relay.close_relay(self.sleep_channel)
        else:
            self.relay.open_relay(self.sleep_channel)

    def supply_off_10ms(self):
        """断电10ms"""
        logger.info('关闭电源')
        self.supply.output(False)
        logger.info('等待0.01s')
        time.sleep(0.01)
        logger.info('打开电源')
        self.supply.output(True)

    def supply_off_40ms(self):
        """断电40ms"""
        logger.info('关闭电源')
        self.supply.output(False)
        logger.info('等待0.04s')
        time.sleep(0.04)
        logger.info('打开电源')
        self.supply.output(True)

    def supply_off_100ms(self):
        """断电40ms"""
        logger.info('关闭电源')
        self.supply.output(False)
        logger.info('等待0.1s')
        time.sleep(0.1)
        logger.info('打开电源')
        self.supply.output(True)

    def supply_off_1s(self):
        """断电1s"""
        logger.info('关闭电源')
        self.supply.output(False)
        logger.info('等待1s')
        time.sleep(1)
        logger.info('打开电源')
        self.supply.output(True)

    def supply_off_3s(self):
        """断电3s"""
        logger.info('关闭电源')
        self.supply.output(False)
        logger.info('等待3s')
        time.sleep(3)
        logger.info('打开电源')
        self.supply.output(True)

    def supply_off_5s(self):
        """断电5s"""
        logger.info('关闭电源')
        self.supply.output(False)
        logger.info('等待5s')
        time.sleep(5)
        logger.info('打开电源')
        self.supply.output(True)

    def set_voltage_24v(self):
        """设置电压为24v"""
        logger.info('设置电压为24V')
        self.supply.set_volt(24)

    def set_voltage_21_7v(self):
        """设置电压为21.7v"""
        logger.info('设置电压为21.7V')
        self.supply.set_volt(21.7)

    def set_voltage_22_5v(self):
        """设置电压为22.5v"""
        logger.info('设置电压为22.5V')
        self.supply.set_volt(22.5)

    def set_voltage_15_5v(self):
        """设置电压为15.5v"""
        logger.info('设置电压为15.5V')
        self.supply.set_volt(15.5)

    def set_voltage_5_3v(self):
        """设置电压为5.3v"""
        logger.info('设置电压为5.3V')
        self.supply.set_volt(5.3)

    def boot_half(self):
        """进入启动状态"""
        logger.info('准备进入启动状态')
        self.supply.set_volt(24)
        self.relay.close_relay(1)
        time.sleep(1)
        self.relay.open_relay(1)
        time.sleep(10)
        logger.info('已进入启动状态')

    def boot_norm(self):
        """进入启动状态"""
        logger.info('正常启动')
        self.supply.set_volt(24)
        self.relay.close_relay(1)
        time.sleep(1)
        self.relay.open_relay(1)
        time.sleep(20)
        logger.info('正常启动完成')

    @staticmethod
    def wait_3s():
        """等待3s"""
        logger.info('等待3s')
        time.sleep(3)

    def reset(self):
        logger.info('复位')
        self.supply.set_volt(24)
        self.supply.output(True)
        self.relay.open_relay(self.sleep_channel)
        self.relay.open_relay(self.supply_channel)
